﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace BenevolentSunData
{
    public class Emitter
    {
        // going to try and avoid an Alive/Dead list
        public List<Particle> Particles = new List<Particle>();

        public Color Color;
        public Vector3 Position;
        public Vector3 SpawnDelta;
        public Vector3 Velocity;
        public Vector3 EndDelta;
        public Vector3 Acceleration;
        public Vector2 Scale;
        public int NumberOfParticles;
        public float ParticleLifeTime;
        public float SpawnRate;
        public float ParticleMass;
        public Random Randomizer;
        public bool GroundCollision;

        public float Counter = 0;

        public Emitter(Color color, Vector3 position, Vector3 spawndelta, Vector3 velocity, Vector3 enddelta, Vector3 acceleration, Vector2 scale, int number, float particleLifeTime, float spawnRate, float particlemass, float gravity, bool groundcollision)
        {
            Randomizer = new Random();
            Color = color;
            Position = position;
            SpawnDelta = spawndelta;
            Velocity = velocity;
            EndDelta = enddelta;
            Acceleration = acceleration;
            Acceleration.Y += gravity;
            Scale = scale;
            NumberOfParticles = number;
            ParticleLifeTime = particleLifeTime;
            SpawnRate = spawnRate;
            ParticleMass = particlemass;
            GroundCollision = groundcollision;
        }

        public void Update(TimeSpan elapsed)
        {
            for (int i = 0; i < Particles.Count; ++i)
            {
                if (Particles[i].LifeTime <= 0.0)
                {
                    Particles.RemoveAt(0);
                    i--;
                    continue;
                }

                // INCREMENTAL EQUATION OF MOTION
                Particles[i].LifeTime -= (float)elapsed.TotalSeconds;
                Particles[i].Velocity += (ParticleMass * Acceleration * (float)elapsed.TotalSeconds);
                if (GroundCollision)
                {
                    if (Particles[i].Position.Y <= 0.0f)
                    {
                        Particles[i].Velocity.Y = -Particles[i].Velocity.Y / 2.0f;
                    }
                }
                Particles[i].Position += Particles[i].Velocity * (float)elapsed.TotalSeconds - 0.5f * ParticleMass * Acceleration * (float)elapsed.TotalSeconds * (float)elapsed.TotalSeconds;

                // NONINCREMENTAL EQUATION OF MOTION
                //Particles[i].Time += (float)elapsed.TotalSeconds;
                //Particles[i].LifeTime -= (float)elapsed.TotalSeconds;
                //Particles[i].Position = 0.5f * ParticleMass * Acceleration * Particles[i].Time * Particles[i].Time +
                //                        Particles[i].SpawnVelocity * Particles[i].Time + 
                //                        Particles[i].StartPosition;
            }

            Counter += (float)elapsed.TotalSeconds;
            while ((Counter >= SpawnRate) && Particles.Count < NumberOfParticles)
            {
                // add particle
                Particle newParticle = new Particle();
                Vector3 spawnPosition = new Vector3(Position.X + GetRandomFloat(-SpawnDelta.X, SpawnDelta.X), Position.Y + GetRandomFloat(-SpawnDelta.Y, SpawnDelta.Y), Position.Z + GetRandomFloat(-SpawnDelta.Z, SpawnDelta.Z));
                Vector3 spawnVelocity = new Vector3(Velocity.X + GetRandomFloat(-EndDelta.X, EndDelta.X), Velocity.Y + GetRandomFloat(-EndDelta.Y, EndDelta.Y), Velocity.Z + GetRandomFloat(-EndDelta.Z, EndDelta.Z));
                newParticle.initParticle(Color,
                                         spawnPosition,
                                         spawnVelocity,
                                         Scale,
                                         ParticleLifeTime);
                Particles.Add(newParticle);
                Counter -= SpawnRate;
            }
        }

        public float GetRandomFloat(float min, float max)
        {
            if (min >= max)
                return min;

            // a random float
            float f = (Randomizer.Next() % 10001) * 0.0001f;
            float ret = (f * (max - min)) + min;
            return ret;
        }

    }
}
